package org.example.study11;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

/**
 * Callable与FutureTask组合使用示例
 * 创建线程计算 1+2+3+...+1000，使用Callable版本
 */
public class CallableExample {

    public static void main(String[] args) {
        System.out.println("主线程开始执行...");

        // 1. 创建Callable任务，指定返回类型为Integer
        // Callable是一个函数式接口，可以使用匿名内部类或Lambda表达式实现
        Callable<Integer> callable = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                System.out.println("计算线程开始执行...");
                int sum = 0;
                // 执行累加计算：1+2+3+...+1000
                for (int i = 1; i <= 1000; i++) {
                    sum += i;
                }
                // 休眠，模拟耗时操作，让效果更明显
                TimeUnit.SECONDS.sleep(2);
                System.out.println("计算线程执行完成，结果: " + sum);
                return sum;  // 返回计算结果
            }
        };

        // 2. 使用FutureTask包装Callable任务
        // FutureTask实现了RunnableFuture接口，既可作为Runnable被线程执行，又可作为Future获取结果
        FutureTask<Integer> futureTask = new FutureTask<>(callable);

        // 3. 创建线程并启动，将FutureTask作为Runnable传递给Thread
        Thread thread = new Thread(futureTask);
        thread.start();

        // 主线程可以继续执行其他任务
        System.out.println("主线程继续执行其他任务...");

        try {
            // 模拟主线程执行其他工作
            TimeUnit.SECONDS.sleep(1);
            System.out.println("主线程其他任务执行完成");

            // 4. 获取计算结果
            // get()方法会阻塞当前线程，直到任务执行完成并返回结果
            System.out.println("主线程开始等待计算结果...");
            Integer result = futureTask.get();

            // 输出最终结果
            System.out.println("最终计算结果: " + result);

        } catch (InterruptedException e) {
            // 处理线程中断异常
            // 当线程在等待过程中被中断时抛出
            System.out.println("线程被中断: " + e.getMessage());
            Thread.currentThread().interrupt(); // 恢复中断状态
        } catch (ExecutionException e) {
            // 处理任务执行异常
            // 当Callable的call方法抛出异常时，会被包装在ExecutionException中
            System.out.println("任务执行出现异常: " + e.getCause().getMessage());
        }

        // 5. 检查任务状态
        System.out.println("任务是否完成: " + futureTask.isDone());
        System.out.println("任务是否被取消: " + futureTask.isCancelled());
    }
}

/*运行：
主线程开始执行...
主线程继续执行其他任务...
计算线程开始执行...
主线程其他任务执行完成
主线程开始等待计算结果...
计算线程执行完成，结果: 500500
最终计算结果: 500500
任务是否完成: true
任务是否被取消: false
*/